﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using BluetoothMachine.Enums;
using BluetoothMachine.ExpandHelper;
using BluetoothMachine.GlobalStatics;
using BluetoothMachine.Models;
using Prism.Commands;
using BluetoothMachine.Entity;
using System.Windows;
using NewLife.Serialization;
using System.Windows.Media;
using BluetoothMachine.Protocols;
using System.IO;
using NPOI.XSSF.UserModel;
using NPOI.SS.UserModel;
using System.Collections.ObjectModel;
using System.Threading;
using System.Diagnostics;
using BluetoothMachine.Lucifer;

namespace BluetoothMachine.ViewModels
{
    public class CoordinatesProductionViewModel
    {
        #region 轴速度
        private int _xSpeed;

        public int XSpeed
        {
            get { return _xSpeed; }
            set { 
                _xSpeed = value;
                ParameterGlobal.ParameterModel.XSpeed = value;
                if (!FixedParameter.IsDeBug) MotorMovements.SetXSpeed(value * 180);
            }
        }


        private int _ySpeed;

        public int YSpeed
        {
            get { return _ySpeed; }
            set { 
                _ySpeed = value;
                ParameterGlobal.ParameterModel.YSpeed = value;
                if (!FixedParameter.IsDeBug) MotorMovements.SetYSpeed(value * 180);
            }
        }

        private int _zSpeed;

        public int ZSpeed
        {
            get { return _zSpeed; }
            set { 
                _zSpeed = value;
                ParameterGlobal.ParameterModel.ZSpeed = value;
                if (!FixedParameter.IsDeBug) MotorMovements.SetZSpeed(value * 360);
            }
        }
        #endregion
        private int _selectedStation;
        /// <summary>
        /// 工位
        /// </summary>
        public int SelectedStation
        {
            get => _selectedStation;
            set
            {
                ParameterGlobal?.SelectPPItems(_selectedStation, value);
                _selectedStation = value;
                if (KeyNameList != null && KeyNameList.Count == 0)
                {
                    KeyNameList.Clear();
                    var list = RemoteControlCoordinates.FindAll(RemoteControlCoordinates._.Aisle == 0 & RemoteControlCoordinates._.ProductModel == ParameterGlobal.ParameterModel.ProductModel);
                    foreach (var item in list)
                    {
                        KeyNameList.Add(item.KeyName);
                    }
                }
            }
        }
        public ObservableCollection<string> KeyNameList { get; set; }
        public string KeyName { get; set; }
        /// <summary>
        /// 坐标点
        /// </summary>
        public ProductionPointModel PPoint { get; set; }

        public ParameterConfigurationGlobal ParameterGlobal { get; set; }
        private HomeGlobal _homeGlobal;
        private DeviceManagementGlobal _device;
        public CoordinatesProductionViewModel(ParameterConfigurationGlobal parameter, HomeGlobal homeGlobal, DeviceManagementGlobal device)
        {
            _homeGlobal = homeGlobal;
            _device = device;
            ParameterGlobal = parameter;
            XSpeed = parameter.ParameterModel.XSpeed;
            YSpeed = parameter.ParameterModel.YSpeed;
            ZSpeed = parameter.ParameterModel.ZSpeed;
            PPoint = new ProductionPointModel();
            SelectedStation = 0;
            KeyNameList = new ObservableCollection<string>();
        }

        public IEnumerable<TaskType> Foods
        {
            get
            {
                foreach (TaskType c in (TaskType[])Enum.GetValues(typeof(TaskType)))
                {
                    yield return c;
                }
            }
        }

        public DelegateCommand AddItem => new DelegateCommand(() =>
        {
            if (!string.IsNullOrEmpty(PPoint.KeyName))
            {
                var model = ProductionPoint.Find(ProductionPoint._.Aisle == SelectedStation & ProductionPoint._.KeyName == PPoint.KeyName & ProductionPoint._.ProductModel == ParameterGlobal.ParameterModel.ProductModel);
                if (model != null) return;
            }
            var entity = new ProductionPoint()
            {
                KeyName = PPoint.KeyName,
                Index = ParameterGlobal.PPItems.Count,
                Ppx = PPoint.Ppx,
                Ppy = PPoint.Ppy,
                Ppz = PPoint.Ppz,
                Aisle = SelectedStation,
                FuncType = PPoint.FuncType,
                IsEnable = true,
                ProductModel = ParameterGlobal.ParameterModel.ProductModel,
            };
            ParameterGlobal.PPItems.Add(entity.ToJson().ToJsonEntity<ProductionPointModel>());
            entity.Insert();
        });

        /// <summary>
        /// 单独Y轴回原点
        /// </summary>
        public DelegateCommand<Button> YAxisBackOrigin => new DelegateCommand<Button>(async sender =>
        {
            sender.IsEnabled = false;
            await Task.WhenAll(
                Task.Run(() => MotorMovements.HomeMove(LTDMC.CardID[0], 1)),
                Task.Run(() => MotorMovements.HomeMove(LTDMC.CardID[0], 4)),
                Task.Run(() => MotorMovements.HomeMove(LTDMC.CardID[0], 7)),
                Task.Run(() => MotorMovements.HomeMove(LTDMC.CardID[1], 2)),
                Task.Run(() => MotorMovements.HomeMove(LTDMC.CardID[1], 5)));
            sender.IsEnabled = true;
        });

        /// <summary>
        /// 屏蔽
        /// </summary>
        public DelegateCommand<Button> ShieldCylinderAction => new DelegateCommand<Button>(sender =>
        {
            if (SelectedStation == -1)
            {
                MessageBox.Show("选择正确的通道");
                return;
            }
            ushort count = (ushort)(SelectedStation * 4);
            if (FixedParameter.IsDeBug) return;
            var communication = _device.ConnectList.FirstOrDefault(x => x.Index == (SelectedStation + 1) & x.CommType == false);
            try
            {
                if (sender.Content.ToString() == "屏蔽气缸伸出")
                {
                    sender.Content = "屏蔽气缸收回";
                    communication.Write(new ModbusRTU(10, true));
                }
                else
                {
                    sender.Content = "屏蔽气缸伸出";
                    communication.Write(new ModbusRTU(10, false));
                }
                _ = communication.Read();
            }
            catch (Exception)
            {
                MessageBox.Show("请先点击运行");
            }
        });

        /// <summary>
        /// 供电气缸
        /// </summary>
        public DelegateCommand<Button> PoweredCylinderAction => new DelegateCommand<Button>(sender =>
        {
            if (SelectedStation == -1)
            {
                MessageBox.Show("选择正确的通道");
                return;
            }
            ushort count = (ushort)(SelectedStation * 4);
            if (FixedParameter.IsDeBug) return;
            var communication = _device.ConnectList.FirstOrDefault(x => x.Index == (SelectedStation + 1) & x.CommType == false);
            try
            {
                if (sender.Content.ToString() == "供电气缸伸出")
                {
                    sender.Content = "供电气缸收回";
                    communication.Write(new ModbusRTU(6, true));
                }
                else
                {
                    sender.Content = "供电气缸伸出";
                    communication.Write(new ModbusRTU(6, false));
                }
                _ = communication.Read();
            }
            catch (Exception)
            {
                MessageBox.Show("请先点击运行");
            }
        });

        public DelegateCommand<Button> ButSave => new DelegateCommand<Button>(sender =>
        {
            ParameterGlobal.Save();
            MessageBox.Show("保存完成！");
        });

        public DelegateCommand<Button> PairCylinderAction => new DelegateCommand<Button>(sender =>
        {
            if (SelectedStation == -1)
            {
                MessageBox.Show("选择正确的通道");
                return;
            }
            if (FixedParameter.IsDeBug) return;
            if (sender.Content.ToString() == "配对气缸伸出")
            {
                sender.Content = "配对气缸收回";
                switch (SelectedStation)
                {
                    case 0:
                        LTDMC.dmc_write_outbit(1, 4, 0);
                        LTDMC.dmc_write_outbit(1, 5, 0);
                        break;
                    case 1:
                        LTDMC.dmc_write_outbit(1, 6, 0);
                        LTDMC.dmc_write_outbit(1, 7, 0);
                        break;
                    case 2:
                        LTDMC.dmc_write_outbit(1, 8, 0);
                        LTDMC.dmc_write_outbit(1, 9, 0);
                        break;
                    case 3:
                        LTDMC.dmc_write_outbit(1, 10, 0);
                        LTDMC.dmc_write_outbit(1, 11, 0);
                        break;
                    case 4:
                        LTDMC.dmc_write_outbit(1, 12, 0);
                        LTDMC.dmc_write_outbit(1, 13, 0);
                        break;
                    default:
                        break;
                }
            }
            else
            {
                sender.Content = "配对气缸伸出";
                switch (SelectedStation)
                {
                    case 0:
                        LTDMC.dmc_write_outbit(1, 4, 1);
                        LTDMC.dmc_write_outbit(1, 5, 1);
                        break;
                    case 1:
                        LTDMC.dmc_write_outbit(1, 6, 1);
                        LTDMC.dmc_write_outbit(1, 7, 1);
                        break;
                    case 2:
                        LTDMC.dmc_write_outbit(1, 8, 1);
                        LTDMC.dmc_write_outbit(1, 9, 1);
                        break;
                    case 3:
                        LTDMC.dmc_write_outbit(1, 10, 1);
                        LTDMC.dmc_write_outbit(1, 11, 1);
                        break;
                    case 4:
                        LTDMC.dmc_write_outbit(1, 12, 1);
                        LTDMC.dmc_write_outbit(1, 13, 1);
                        break;
                    default:
                        break;
                }
            }
        });

        public DelegateCommand<Button> CylinderAction => new DelegateCommand<Button>(sender =>
        {
            if (SelectedStation == -1)
            {
                MessageBox.Show("选择正确的通道");
                return;
            }
            ushort count = (ushort)(SelectedStation * 4);
            if (FixedParameter.IsDeBug) return;
            if (sender.Content.ToString() == "按键气缸伸出")
            {
                sender.Content = "按键气缸收回";
                KEYDomwn(count, 0);
            }
            else
            {
                sender.Content = "按键气缸伸出";
                KEYDomwn(count, 1);
            }
        });

        private void KEYDomwn(ushort count, ushort value)
        {
            LTDMC.dmc_write_outbit((ushort)(count > 15 ? 1 : 0), (ushort)(count % 16), value);
            LTDMC.dmc_write_outbit((ushort)(count > 15 ? 1 : 0), (ushort)((count + 1) % 16), value);
            LTDMC.dmc_write_outbit((ushort)(count > 15 ? 1 : 0), (ushort)((count + 2) % 16), value);
            LTDMC.dmc_write_outbit((ushort)(count > 15 ? 1 : 0), (ushort)((count + 3) % 16), value);
        }

        public DelegateCommand<string> AxisMovementDown => new DelegateCommand<string>(sender =>
        {
            if (SelectedStation == -1)
            {
                MessageBox.Show("选择正确的通道");
                return;
            }
            _buttonName = sender;
            if (!FixedParameter.IsDeBug)
            {
                ushort count = (ushort)(SelectedStation * 3);
                ushort fx = 1;
                switch (sender)
                {
                    case "左 X":
                        fx = 0;
                        break;
                    case "X 右":
                        break;
                    case "后 Y":
                        fx = 0;
                        count += 1;
                        break;
                    case "Y 前":
                        count += 1;
                        break;
                    case "上 Z":
                        fx = 0;
                        count += 2;
                        break;
                    case "Z 下":
                        count += 2;
                        break;
                    default:
                        break;
                }
                LTDMC.dmc_vmove(LTDMC.CardID[count > 7 ? 1 : 0], (ushort)(count % 8), fx);
            }
        });
        private string _buttonName = null;
        public DelegateCommand<string> AxisMovementUp => new DelegateCommand<string>(async sender =>
        {
            if (SelectedStation == -1)
            {
                MessageBox.Show("选择正确的通道");
                return;
            }
            if (!FixedParameter.IsDeBug)
            {
                await Task.Run(() =>
                {
                    ushort count = (ushort)(SelectedStation * 3);
                    if (_buttonName == "左 X" || _buttonName == "X 右") PPoint.Ppx = DmcStop(count, 0.02);
                    if (_buttonName == "后 Y" || _buttonName == "Y 前")
                    {
                        count += 1;
                        PPoint.Ppy = DmcStop(count, 0.02);
                    }
                    if (_buttonName == "上 Z" || _buttonName == "Z 下")
                    {
                        count += 2;
                        PPoint.Ppz = DmcStop(count,0.005);
                    }
                });
            }
        });

        /// <summary>
        /// 流程清空
        /// </summary>
        public DelegateCommand<Button> ProcessEmpty => new DelegateCommand<Button>(sender =>
        {
            sender.IsEnabled = false;
            var list = ProductionPoint.FindAll(ProductionPoint._.Aisle == SelectedStation & ProductionPoint._.ProductModel == ParameterGlobal.ParameterModel.ProductModel);
            foreach (var item in list)
            {
                item.Delete();
            }
            ParameterGlobal?.SelectPPItems(-1, SelectedStation);
            sender.IsEnabled = true;
        });

        /// <summary>
        /// 按键坐标计算
        /// </summary>
        public DelegateCommand<Button> KeyCoordinateCalculation => new DelegateCommand<Button>(sender =>
        {
            sender.IsEnabled = false;
            var model = ProductionPoint.Find(ProductionPoint._.Aisle == SelectedStation & ProductionPoint._.KeyName == "电源" & ProductionPoint._.ProductModel == ParameterGlobal.ParameterModel.ProductModel);
            if (model == null)
            {
                MessageBox.Show("请先添加电源按键");
                sender.IsEnabled = true;
                return;
            }
            foreach (var item in ParameterGlobal.RCCItems)
            {
                if (item.KeyName == "电源") continue;
                var entity = ProductionPoint.Find(ProductionPoint._.Aisle == SelectedStation & ProductionPoint._.KeyName == item.KeyName & ProductionPoint._.ProductModel == ParameterGlobal.ParameterModel.ProductModel);
                entity.Ppx = item.Rccx + model.Ppx;
                entity.Ppy = item.Rccy + model.Ppy;
                entity.Ppz = item.Rccz + model.Ppz;
                entity.Update();
            }
            ParameterGlobal?.SelectPPItems(-1, SelectedStation);
            sender.IsEnabled = true;
        });

        /// <summary>
        /// 一键生成
        /// </summary>
        public DelegateCommand<Button> KeyGeneration => new DelegateCommand<Button>(sender =>
        {
            sender.IsEnabled = false;
            var model = ProductionPoint.Find(ProductionPoint._.Aisle == SelectedStation & ProductionPoint._.KeyName == "电源" & ProductionPoint._.ProductModel == ParameterGlobal.ParameterModel.ProductModel);
            if (model == null)
            {
                MessageBox.Show("请先添加电源按键");
                sender.IsEnabled = true;
                return;
            }
            foreach (var item in ParameterGlobal.RCCItems)
            {
                var entity = new ProductionPoint()
                {
                    KeyName = item.KeyName,
                    Index = ParameterGlobal.PPItems.Count,
                    Ppx = item.Rccx + model.Ppx,
                    Ppy = item.Rccy + model.Ppy,
                    Ppz = item.Rccz + model.Ppz,
                    Aisle = SelectedStation,
                    FuncType = "按键测试",
                    IsEnable = true,
                    ProductModel = ParameterGlobal.ParameterModel.ProductModel,
                };
                entity.Insert();
            }
            ParameterGlobal?.SelectPPItems(-1, SelectedStation);
            sender.IsEnabled = true;
        });

        /// <summary>
        /// 流程复制
        /// </summary>
        public DelegateCommand<Button> DuplicateCoordinateSystem => new DelegateCommand<Button>(sender =>
        {
            if (SelectedStation == 0)
            {
                MessageBox.Show("不能选择第一通道复制！");
                return;
            }
            sender.IsEnabled = false;
            var list = ProductionPoint.FindAll(ProductionPoint._.Aisle == 0 & ProductionPoint._.ProductModel == ParameterGlobal.ParameterModel.ProductModel);
            for (int i = 1; i < 5; i++)
            {
                foreach (var item in list)
                {
                    new ProductionPoint()
                    {
                        Index = item.Index,
                        Aisle = i,
                        FuncType = item.FuncType,
                        KeyName = item.KeyName,
                        Ppx = item.Ppx,
                        Ppy = item.Ppy,
                        Ppz = item.Ppz,
                        ProductModel = item.ProductModel,
                        IsEnable = item.IsEnable,
                    }.Insert();
                }
            }
            sender.IsEnabled = true;
        });

        public DelegateCommand SourceUpdated => new DelegateCommand(() =>
        {
            for (int i = 0; i < ParameterGlobal.PPItems.Count; i++)
            {
                ParameterGlobal.PPItems[i].Index = i;
                ProductionPoint.Update(ProductionPoint._.Index == i, ProductionPoint._.ID == ParameterGlobal.PPItems[i].ID);
            }
        });

        private double DmcStop(ushort count, double value)
        {
            LTDMC.dmc_stop(LTDMC.CardID[count > 7 ? 1 : 0], (ushort)(count % 8), 0);
            MotorMovements.WaitAxisMovement(LTDMC.CardID[count > 7 ? 1 : 0], (ushort)(count % 8));
            int pulse = LTDMC.dmc_get_position(LTDMC.CardID[count > 7 ? 1 : 0], (ushort)(count % 8));
            _homeGlobal.MessagesList[0].Insert(0, new RunMessage() { RunTime = DateTime.Now.ToString("T"), Message = $"脉冲数：{pulse}", MessageForeground = Brushes.Black });
            return (double)(pulse * value);
        }
        public DelegateCommand Delete => new DelegateCommand(() => ParameterGlobal.DelectPP(PPoint));
        public DelegateCommand<ProductionPointModel> SelectUpdate => new DelegateCommand<ProductionPointModel>(sender =>
        {
            if (sender == null) return;
            PPoint.KeyName = sender.KeyName;
            PPoint.IsEnable = sender.IsEnable;
            PPoint.Ppx = sender.Ppx;
            PPoint.Ppy = sender.Ppy;
            PPoint.Ppz = sender.Ppz;
            PPoint.ProductModel = sender.ProductModel;
            PPoint.Aisle = sender.Aisle;
            PPoint.FuncType = sender.FuncType;
            PPoint.Index = sender.Index;

            _entity = ProductionPoint.Find(
                ProductionPoint._.ProductModel == PPoint.ProductModel
                & ProductionPoint._.FuncType == PPoint.FuncType
                & ProductionPoint._.Index == PPoint.Index
                & ProductionPoint._.Aisle == PPoint.Aisle);
            log4net.LogManager.GetLogger("message").Info($"数据：{PPoint.ProductModel}--{PPoint.FuncType}--{PPoint.Index}--{PPoint.Aisle}\r\n");
        });

        public DelegateCommand SaveData => new DelegateCommand(() => ParameterGlobal.SavePP(PPoint, _entity, SelectedStation));
        private ProductionPoint _entity;
        public DelegateCommand<Button> SingleStep => new DelegateCommand<Button>(async sender => {
            sender.IsEnabled = false;
            ushort count = (ushort)(SelectedStation * 3);
            await Task.Run(() =>
            {
                MotorMovements.HomeMove(LTDMC.CardID[(count + 2) > 7 ? 1 : 0], (ushort)((count + 2) % 8));
                MotorMovements.XYMove(LTDMC.CardID[count > 7 ? 1 : 0], new ushort[] { (ushort)(count % 8), (ushort)((count + 1) % 8) }, new double[] { PPoint.Ppx, PPoint.Ppy });
                if (PPoint.Ppz != 0) MotorMovements.ShaftOperation(LTDMC.CardID[(count + 2) > 7 ? 1 : 0], (ushort)((count + 2) % 8), (int)(PPoint.Ppz / 0.005));
            });
            sender.IsEnabled = true;
        });

        /// <summary>
        /// 导入快速对点
        /// </summary>
        public DelegateCommand InputData => new DelegateCommand(() =>
        {
            Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog();
            openFileDialog.Title = "选择文件";
            openFileDialog.Filter = "文件(*.*)|*.*";
            openFileDialog.FilterIndex = 1;
            openFileDialog.ValidateNames = false;
            openFileDialog.CheckFileExists = true;
            openFileDialog.CheckPathExists = true;
            openFileDialog.Multiselect = false;//允许同时选择多个文件
            if (openFileDialog.ShowDialog() == true)
            {
                try
                {
                    using var stream = new FileStream(openFileDialog.FileName, FileMode.Open);
                    IWorkbook wb = new XSSFWorkbook(stream);
                    ISheet sheet = wb.GetSheetAt(0);
                    RemoteControlCoordinatesModel model = new RemoteControlCoordinatesModel();
                    for (int r = 1; r < sheet.LastRowNum + 1; r++)
                    {
                        IRow currentRow = sheet.GetRow(r);
                        for (int c = 0; c < currentRow.LastCellNum; c++)
                        {
                            ICell cell = currentRow.GetCell(c);
                            if (cell != null)
                            {
                                switch (c)
                                {
                                    case 0: model.KeyName = cell.StringCellValue; break;
                                    case 1: model.Rccx = cell.NumericCellValue; break;
                                    case 2: model.Rccy = cell.NumericCellValue; break;
                                    case 3: model.Rccz = cell.NumericCellValue; break;
                                }
                            }
                        }
                        new RemoteControlCoordinates()
                        {
                            KeyName = model.KeyName,
                            Rccx = model.Rccx,
                            Rccy = model.Rccy,
                            Rccz = model.Rccz,
                            ProductModel = ParameterGlobal.ParameterModel.ProductModel
                        }.Insert();
                        ParameterGlobal.RCCItems.Add(new RemoteControlCoordinatesModel()
                        {
                            KeyName = model.KeyName,
                            Rccx = model.Rccx,
                            Rccy = model.Rccy,
                            Rccz = model.Rccz,
                        });
                    }
                    wb.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
        });

        /// <summary>
        /// 读取红外数据
        /// </summary>
        public DelegateCommand<Button> ReadInfrared => new DelegateCommand<Button>(async sender =>
        {
            sender.IsEnabled = false;
            await Task.Run(() =>
            {
                ICommunication eio = _device.ConnectList.FirstOrDefault(x => x.Index == 1 & x.CommType);
                var eio1 = _device.ConnectList.FirstOrDefault(x => x.Index == 1 & x.CommType == false);
                var model = ProductionPoint.Find(ProductionPoint._.Aisle == 0 & ProductionPoint._.ProductModel == ParameterGlobal.ParameterModel.ProductModel & ProductionPoint._.KeyName == KeyName);
                var eneity = ParameterGlobal.PPItems.FirstOrDefault(x => x.ProductModel == ParameterGlobal.ParameterModel.ProductModel & x.KeyName == KeyName);
                if (model == null || eneity == null) return;
                //MotorMovements.HomeMove(0, 2);
                MotorMovements.XYMove(0, new ushort[] { 0, 1 }, new double[] { model.Ppx, model.Ppy });
                if (model.Ppz != 0) MotorMovements.ShaftOperation(0, 2, (int)(model.Ppz / 0.005));
                Thread.Sleep(500);
                try
                {
                    SendIOControl(eio1, new byte[] { 7, 8 });
                    Thread.Sleep(1000);
                    eio.Write(new byte[] { 0x68, 0x11, 0x11, 0x11, 0x16, 0x0D, 0x0A });
                    _ = eio.Read();
                    Thread.Sleep(1000);
                    eio.Write(new byte[] { 0x68, 0x22, 0x22, 0x22, 0x16, 0x0D, 0x0A });
                    _ = eio.Read();
                    Stopwatch stopwatch = new Stopwatch();
                    LTDMC.dmc_write_outbit(0, 1, 0);
                    LTDMC.dmc_write_outbit(0, 3, 0);
                    stopwatch.Restart();
                    while (stopwatch.ElapsedMilliseconds < ParameterGlobal.ParameterModel.TimeKey)
                    {
                        Thread.Sleep(5);
                    }
                    LTDMC.dmc_write_outbit(0, 1, 1);
                    LTDMC.dmc_write_outbit(0, 3, 1);
                    var bytes = eio.Read();
                    eneity.InfraredData = BitConverter.ToString(bytes);
                    model.InfraredData = BitConverter.ToString(bytes);
                    model.Update();
                    eio.Write(new byte[] { 0x68, 0x33, 0x33, 0x33, 0x16, 0x0D, 0x0A });
                    _ = eio.Read();
                    Thread.Sleep(500);
                    SendIOControl(eio1, new byte[] { 7, 8 }, false);
                }
                catch (Exception)
                {
                }
            });
            sender.IsEnabled = true;
        });

        /// <summary>
        /// 控制扩展IO
        /// </summary>
        /// <param name="communication">通信接口</param>
        /// <param name="bytes">0-15</param>
        /// <param name="index">通道号左右</param>
        /// <returns></returns>
        private bool SendIOControl(ICommunication communication, byte[] bytes, bool oddEvent = true)
        {
            try
            {
                int count = 1;
            This:
                communication.Write(new ModbusRTU(bytes[0], oddEvent));
                Thread.Sleep(30);
                byte[] rst = communication.Read();
                Thread.Sleep(10);
                if (bytes[1] != 99)
                {
                    communication.Write(new ModbusRTU(bytes[1], oddEvent));
                    Thread.Sleep(30);
                    _ = communication.Read();
                }
                if (rst != null) return true;
                else
                {
                    if (count == 1)
                    {
                        count--;
                        goto This;
                    }
                }
                return false;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }
}
